package tech.abing.spider.util;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.csvreader.CsvWriter;
import com.google.common.collect.Lists;
import tech.abing.spider.annotation.CsvField;
import tech.abing.spider.task.model.CloseEntity;

/**
 * CSV文件处理工具类
 * 
 * @Description: CSV文件处理工具类
 * @author Ivan 2862099249@qq.com
 * @date 2015年3月19日 下午6:02:33
 * @version V1.0
 */
public class CsvUtil {

	private static Logger LOG = LoggerFactory.getLogger(CsvUtil.class);

	private CsvWriter cw;

	private List<Object[]> annotationList = Lists.newArrayList();

	public CsvUtil(Class<?> cls, String filePath) {
		this(cls, ',', filePath);
	}
	
	public CsvUtil(Class<?> cls, char delimiter, String filePath) {

		File csv = new File(filePath);
		// 如果文件存在则删除
		if (csv.exists()) {
			csv.delete();
		}
		//创建文件及文件所在的父级目录
		FileUtils.createFile(filePath);
		try {
			cw = new CsvWriter(new FileWriter(csv), delimiter);

			Field[] fs = cls.getDeclaredFields();
			for (Field f : fs) {
				// 获取字段上的注解
				CsvField ef = f.getAnnotation(CsvField.class);
				if (ef != null) {
					annotationList.add(new Object[] { ef, f });
				}
			}

			Method[] ms = cls.getDeclaredMethods();
			for (Method m : ms) {
				// 获取方法上的注解
				CsvField ef = m.getAnnotation(CsvField.class);
				if (ef != null) {
					annotationList.add(new Object[] { ef, m });
				}
			}

			// 字段排序
			Collections.sort(annotationList, new Comparator<Object[]>() {
				public int compare(Object[] o1, Object[] o2) {
					return new Integer(((CsvField) o1[0]).sort()).compareTo(new Integer(((CsvField) o2[0]).sort()));
				};
			});

			for (Object[] os : annotationList) {
				// 取得注解上的表头名称
				String title = ((CsvField) os[0]).title();
				cw.write(title);
			}
			cw.endRecord();// 写完表头

		} catch (IOException e) {
			LOG.error("Write Csv header error!", e);
		}

	}

	/**
	 * 将数据集导出为CSV文件
	 * 
	 * @param dataList
	 *            数据集
	 * @param delimiter
	 *            CSV字段的分割符
	 * @param filePath
	 *            生成文件的存在地
	 */
	public <T> void setCsvData(List<T> dataList) {
		String className = "";
		for (T t : dataList) {
			if(StringUtils.isBlank(className)){
				className = t.getClass().getSimpleName();
			}
			try {
				for (Object[] os : annotationList) {
					CsvField cf = (CsvField) os[0];
					Object val = null;
					// Get entity value
					if (os[1] instanceof Field) {
						val = Reflections.invokeGetter(t, ((Field) os[1]).getName());
					} else if (os[1] instanceof Method) {
						val = Reflections.invokeMethod(t, ((Method) os[1]).getName(), new Class[] {}, new Object[] {});
					}
					if (val == null) {
						// 取得默认值
						String defaultValue = cf.defaultValue();
						if (StringUtils.isNotBlank(defaultValue)) {
							val = defaultValue;
						}
					}
					cw.write(val.toString());
				}
				cw.endRecord();// 写完一行
			} catch (IOException e) {
				LOG.error("Write Csv data[" + t.toString() + "] error!", e);
			}
		}

	}

	/**
	 * 清理资源，并写入数据
	 */
	public void dispose() {
		if (cw != null) {
			cw.close();
		}
	}
	
	public void flush() {
		if (cw != null) {
			cw.flush();
		}
	}

	public static void main(String[] args) {

		CsvUtil csv = new CsvUtil(CloseEntity.class, "data/crawl/close.csv");

		List<CloseEntity> dataList = new ArrayList<CloseEntity>();

		CloseEntity c1 = new CloseEntity();
		c1.setCloseTime("sdf");
		c1.setCount(1);
		c1.setHostIp("192.168.1.101");
		c1.setHostName("crawl01");
		c1.setProdId("aaa");
		c1.setUrl("http://localhost:8080/syybi/");
		
		CloseEntity c2 = new CloseEntity();
		c2.setCloseTime("sdf2");
		c2.setCount(2);
		c2.setHostIp("192.168.1.102");
		c2.setHostName("crawl02");
		c2.setProdId("aa2a");
		c2.setUrl("http://localhost:8080/syybi/2");
		
		dataList.add(c1);
		dataList.add(c2);
		
		csv.setCsvData(dataList);

		csv.dispose();

	}

}
